package com.swak.frame.filter.adapter;

import java.util.List;

import com.swak.frame.chain.Filter;
import com.swak.frame.chain.FilterChain;
import com.swak.frame.chain.FilterInvoker;
import com.swak.frame.common.SpringBeanFactory;

/**
 * BeanName责任链模式工厂
 * 
 * @author colley.ma
 * @date 2018/04/17
 */
public class BeanFilterChainFactoryAdapter<T> implements FilterChainFactoryAdapter<T> {

    private List<Class<Filter<T>>> filterClsList;

    private FilterChain<T> filterChain;

    private FilterChain<T> buildFilterChain(List<Class<Filter<T>>> filterClsList) {
        FilterInvoker<T> last = new FilterInvoker<T>() {};
        FilterChain<T> filterChain = new FilterChain<T>();
        for (int i = filterClsList.size() - 1; i >= 0; i--) {
            FilterInvoker<T> next = last;
            Filter<T> filter = SpringBeanFactory.getBean(filterClsList.get(i));
            last = new FilterInvoker<T>() {
                @Override
                public void invoke(T context) {
                    filter.doFilter(context, next);
                }
            };
        }
        filterChain.setHeader(last);
        return filterChain;
    }

    @Override
    public FilterChain<T> getFilterChain() {
        if (this.filterChain == null) {
            this.filterChain = buildFilterChain(filterClsList);
        }
        return this.filterChain;
    }
}
